package com.atguigu.publisher.service.impl;

import com.atguigu.common.logger.GmallConstants;
import com.atguigu.publisher.bean.GroupByAggs;
import com.atguigu.publisher.bean.OrderDetail;
import com.atguigu.publisher.service.OrderDetailService;
import io.searchbox.client.JestClient;
import io.searchbox.core.Search;
import io.searchbox.core.SearchResult;
import io.searchbox.core.search.aggregation.MetricAggregation;
import io.searchbox.core.search.aggregation.TermsAggregation;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.TermsBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * project : gmall-parent
 * package : com.atguigu.publisher.service.impl
 *
 * author WangJX  date 2019/12/4 20:22  version 1.0
 */

@Service
public class OrderDetailServiceImpl implements OrderDetailService {

    @Autowired
    JestClient jestClient;

    @Override
    public Map<String, Object> getSaleDetail(String date, String keyword, int pageSize, int pageNo) {
        //创建ES搜索语句实例
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        //查询
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.filter(new TermQueryBuilder("dt", date));
        boolQueryBuilder.must(new MatchQueryBuilder("sku_name", keyword).operator(MatchQueryBuilder.Operator.AND));
        sourceBuilder.query(boolQueryBuilder);

        //聚合
        TermsBuilder genderAggs = AggregationBuilders.terms("groupby_gender").field("user_gender").size(2);
        TermsBuilder ageAggs = AggregationBuilders.terms("groupby_age").field("user_age").size(100);
        sourceBuilder.aggregation(genderAggs);
        sourceBuilder.aggregation(ageAggs);

        //分页
        int size = (pageNo - 1) * pageSize;
        sourceBuilder.from(size);
        sourceBuilder.size(pageSize);


        //ES执行查询
        Search search = new Search.Builder(sourceBuilder.toString())
                .addIndex(GmallConstants.ES_INDEX_SALE_DETAIL)
                .addType("_doc")
                .build();


        Map<String, Object> map = new HashMap<>();
        try {
            //使用ES Search查询数据
            SearchResult execute = jestClient.execute(search);

            //总数
            Long total = execute.getTotal();

            //明细
            List<OrderDetail> list = new ArrayList<>();
            //查询出的结果
            List<SearchResult.Hit<OrderDetail, Void>> hits = execute.getHits(OrderDetail.class);
            for (SearchResult.Hit<OrderDetail, Void> hit : hits) {
                list.add(hit.source);
            }

            //聚合
            List<GroupByAggs> listAggByGender = new ArrayList<>();
            List<TermsAggregation.Entry> groupby_gender = execute.getAggregations().getTermsAggregation("groupby_gender").getBuckets();
            for (TermsAggregation.Entry entry : groupby_gender) {
                GroupByAggs groupByAggs = new GroupByAggs(entry.getKey(), entry.getCount());
                listAggByGender.add(groupByAggs);
            }

            List<GroupByAggs> listAggByAge = new ArrayList<>();
            List<TermsAggregation.Entry> groupby_age = execute.getAggregations().getTermsAggregation("groupby_age").getBuckets();
            for (TermsAggregation.Entry entry : groupby_age) {
                GroupByAggs groupByAggs = new GroupByAggs(entry.getKey(), entry.getCount());
                listAggByAge.add(groupByAggs);
            }



            map.put("total", total);
            map.put("detail", list);
            map.put("groupby_gender", listAggByGender);
            map.put("groupby_age", listAggByAge);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return map;
    }
}
